home *** CD-ROM | disk | FTP | other *** search
- /* ------------------------------------------------------------------
- MML compiler [M2]
- programmed by S.Yamamoto (SHINNOSUKE)
- m2comp.c -- MML compile Main
- ------------------------------------------------------------------ */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <ctype.h>
- #include <string.h>
- #include <limits.h>
- #include "m2.h"
-
- #define SUCCSESS 0
- #define FAILURE (-1)
- #define TRUE 1
- #define FALSE 0
- #define ERR (-1)
- #define YES 1
- #define NO 0
-
- #define PART_MAX 16
- #define ARAY_MAX 16
- #define EXCL_MAX 128
-
- #define EXCM 0xf0
- #define TEMPO 0xf7
- #define SIGNATURE 0xf8
- #define MEMO 0xf1
- #define WORDS 0xf2
- #define F7EXCM 0xf3
- #define DIRECT 0xf4
-
- #define ABS(x) ((x)>0?(x):-(x))
- #define CHECKSUM(x) (((x)%128!=0)?128-(x)%128:0) /* EXCLUSIVE SUM */
-
- #define RUNNING 1
- #define SHIFTST 2
- #define HISPCMP 4
- #define CHECKMD 8
-
- char *EMG_v = "velocity";
- char *EMG_o = "octave";
- char *EMG_q = "q";
- char *EMG_l = "length";
-
- char *rp;
- char *exclPt[EXCL_MAX]; /* Exclusive pointer */
-
- char key_spart[16] = {0,0,0,0 ,0,0,0,0 ,0,0,0,0 ,0,0,0,0};
- int key_shift = 0;
-
- int dlt_v[PART_MAX][ARAY_MAX];
- int dlt_o[PART_MAX][ARAY_MAX];
- int dlt_q[PART_MAX][ARAY_MAX];
- int dlt_l[PART_MAX][ARAY_MAX];
-
- int tie_flag;
- int tie_note;
- int tie_etct; /* タイコマンド用 */
-
- int exclCt; /* Exclusive count */
- int nowPart;
- int nowAray;
- int dltAray[PART_MAX];
-
- int evntCt;
-
- int option; /* option status */
-
- unsigned short maxTCt;
- unsigned short setTime[128];
-
- WORKMEM *evntBuf;
- FLGDAT fg;
-
- static int ctrlMacro[][7] =
- {/* Num,Mode,Min,Max,+(para default),*,default */
- {ERR,ERR,ERR,ERR,ERR,ERR,ERR},
- {0,0,0,127,0,1,0}, /* b/Bank Select */
- {10,1,ERR,ERR,64,1,ERR}, /* c/Panpot Center */
- {ERR,ERR,ERR,ERR,ERR,ERR,ERR},
- {11,0,0,127,0,1,127}, /* e/Expression */
- {69,0,0,1,0,127,0}, /* f/freeze */
- {ERR,ERR,ERR,ERR,ERR,ERR,ERR},
- {64,0,0,1,0,127,0}, /* h/Hold1 */
- {ERR,ERR,ERR,ERR,ERR,ERR,ERR},
- {ERR,ERR,ERR,ERR,ERR,ERR,ERR},
- {ERR,ERR,ERR,ERR,ERR,ERR,ERR},
- {10,0,0,64,64,-1,63}, /* l/Panpot Left */
- {1,0,0,127,0,1,0}, /* m/Modulation depth */
- {66,0,0,1,0,127,0}, /* n/Sostenuto */
- {93,0,0,127,0,1,0}, /* o/chorus send level(ef3) */
- {65,0,0,1,0,127,0}, /* p/Portamento */
- {ERR,ERR,ERR,ERR,ERR,ERR,ERR},
- {10,0,0,63,64,1,63}, /* r/Panpot Right */
- {67,0,0,1,0,127,0}, /* s/Soft pedal */
- {5,0,0,127,0,1,0}, /* t/portamento time */
- {ERR,ERR,ERR,ERR,ERR,ERR,ERR},
- {7,0,0,127,0,1,100}, /* v/volume */
- {ERR,ERR,ERR,ERR,ERR,ERR,ERR},
- {ERR,ERR,ERR,ERR,ERR,ERR,ERR},
- {ERR,ERR,ERR,ERR,ERR,ERR,ERR},
- {ERR,ERR,ERR,ERR,ERR,ERR,ERR}
- };
-
- void dltSet( void ) /* 省略値の初期化 */
- {
- int i;
- int j;
-
- for( i=0;i<PART_MAX;i++ ) {
- for( j=0;j<ARAY_MAX;j++ ) {
- dlt_v[i][j] = 127;
- dlt_o[i][j] = 4;
- dlt_q[i][j] = 8;
- dlt_l[i][j] = 4;
- }
- }
- return;
- }
-
- /* データ読み込み・書き込みなど */
-
- int readData( void ) /* 文字の読み込み */
- {
- int ret;
-
- skipLine( &rp );
- ret = *rp;
- return( ret );
- }
-
- int readPara( int min ,int max ,int d ,char *m ) /* 数字の読み込み */
- {
- int ret;
-
- skipLine( &rp );
- ret = strToInt( &rp ,min ,max ,d ,m );
- return( ret );
- }
-
- int blockName( void ) /* ブロックネームを読み飛ばす */
- {
- int b;
- int flag = 0;
-
- for(;;) {
- b = readData();
- if( b == '{' )
- break;
- if( b == '\0' )
- return( FAILURE );
- rp++;
- if( b< ' ' || b > '~' )
- continue;
- if( flag == 0 )
- putDisp( "process:" );
- putDisp( "%c",b );
- flag = 1;
- }
- rp++;
- if( flag == 1 )
- putDisp("\n");
- return( SUCCSESS );
- }
-
- void getPart( void ) /* パート&配列番号を得る */
- {
- nowPart = readPara( 1 ,PART_MAX ,-1 ,"(part number)" ) - 1;
-
- if( readData() == '[' ) {
- rp++;
- dltAray[nowPart] = readPara( 0 ,ARAY_MAX-1 ,dltAray[nowPart]
- ,"(array number)" );
- if( readData() != ']' )
- errMsg( MSG_syntax ,"array" );
- rp++;
- };
-
- nowAray = dltAray[nowPart];
- dltAray[nowPart]++;
- if( dltAray[nowPart] >= ARAY_MAX )
- dltAray[nowPart]=0;
-
- if( readData() != '=' )
- errMsg( MSG_misopd ,"not found '='" );
- rp++;
- return;
- }
-
- void exclBank( unsigned short t ,int m ,int l ,char *s )
- {
- int i;
-
- evntPut( t ,m ,exclCt ,l);
- if(( exclPt[exclCt] = malloc( l )) == NULL)
- errMsg( MSG_cntalc ,"excl/word" );
-
- for( i=0;i<l;i++ ) {
- exclPt[exclCt][i] = *s;
- s++;
- }
- exclCt++;
- return;
- }
-
- /* イベント処理系 */
-
- void evntPut(unsigned short c ,int d1 ,int d2 ,int d3 ) /* 記憶 */
- {
- if( evntCt >= fg.wksize )
- errMsg( MSG_outwka ,NULL );
-
- evntBuf[evntCt].num = (unsigned short) evntCt;
- evntBuf[evntCt].ct = (unsigned short) c;
- evntBuf[evntCt].dat[0] = (unsigned char) d1;
- evntBuf[evntCt].dat[1] = (unsigned char) d2;
- evntBuf[evntCt].dat[2] = (unsigned char) d3;
- evntCt++;
- return;
- }
-
- void evntSort( void ) /* イベントをソート */
- {
- /* 基本選択法 */
- int i;
- int j;
- int s;
-
- unsigned short min;
- WORKMEM dummy;
-
- for( i=0;i<evntCt-1;i++ ) {
- min = evntBuf[i].ct;
- s = i;
- for( j=i+1;j<evntCt;j++ ) {
- if( evntBuf[j].ct < min || (evntBuf[j].ct == min
- && evntBuf[j].num < evntBuf[s].num )) {
- min = evntBuf[j].ct;
- s = j;
- }
- }
- dummy = evntBuf[i];
- evntBuf[i] = evntBuf[s];
- evntBuf[s] = dummy;
- }
- return;
- }
-
- void evntSort2( void ) /* イベントをソート(高速モード) */
- {
- /* ヒープソート
- 動作チェックで,完全に安定したソートができていないことがわかった。
- */
- int i;
- int j;
- int k;
- int n = evntCt;
-
- WORKMEM x;
-
- for ( k=n/2;k>=1;k-- ) {
- i = k;
- x = evntBuf[i-1];
- while((j = 2 * i) <= n) {
- if (j< n && evntBuf[j-1].ct < evntBuf[j].ct) j++;
- if (evntBuf[j-1].ct == evntBuf[j].ct) {
- if(j < n && evntBuf[j-1].num <= evntBuf[j].num )
- j++;
- }
- if (x.ct > evntBuf[j-1].ct) break;
- if (x.ct == evntBuf[j-1].ct) {
- if(x.num >= evntBuf[j-1].num) break;
- }
- evntBuf[i-1] = evntBuf[j-1];
- i = j;
- }
- evntBuf[i-1] = x;
- }
- while (n > 1) {
- x = evntBuf[n-1];
- evntBuf[n-1] = evntBuf[0];
- n--;
- i = 1;
- while ((j = 2 * i) <= n) {
- if (j < n && evntBuf[j-1].ct < evntBuf[j].ct) j++;
- if (evntBuf[j-1].ct == evntBuf[j].ct) {
- if(j < n && evntBuf[j-1].num <= evntBuf[j].num) j++;
- }
- if (x.ct > evntBuf[j-1].ct) break;
- if (x.ct == evntBuf[j-1].ct) {
- if(x.num >= evntBuf[j-1].num) break;
- }
- evntBuf[i-1] = evntBuf[j-1];
- i = j;
- }
- evntBuf[i-1] = x;
- }
- return;
- }
-
- void evntCheck( void ) /* イベントをチェック */
- {
- unsigned int i;
- unsigned int c = 0;
- unsigned int n = 0;
-
- printf( "No. Time Pri. MIDI Para.\n" );
-
- for( i=0;i<evntCt;i++ ) {
- printf( "%05u %05u %05u %02X %03u %03u\n",i ,evntBuf[i].ct
- ,evntBuf[i].num ,evntBuf[i].dat[0]
- ,evntBuf[i].dat[1] ,evntBuf[i].dat[2] );
-
- if ( i != 0 ) {
- if( c == evntBuf[i].ct ) {
- if( n > evntBuf[i].num )
- printf( "Warning:Sort error\n" );
- }
- }
- c = evntBuf[i].ct;
- n = evntBuf[i].num;
- }
- return;
- }
-
- void evntRtch( void ) /* イベントを修正 */
- {
- int e;
- int i;
- int flag = FALSE;
-
- unsigned short max;
- unsigned short t1;
- unsigned short t2;
-
- max = evntBuf[evntCt-1].ct;
- for( i=0;i<evntCt-2;i++ ) {
- e = (evntBuf[i].dat[0]) & 0xf0;
- if( e==0xb0 || e==0xc0 || e==0xe0 || e==0xf0 ) {
- if( flag == FALSE ) {
- t1 = evntBuf[i].ct;
- t2 = evntBuf[i].ct;
- flag = TRUE;
- continue;
- }
- if( t1 == evntBuf[i].ct ) {
- t2++;
- if( t2 <= max ) evntBuf[i].ct = t2;
- continue;
- }
- t1 = evntBuf[i].ct;
- if( t1 > t2 ) t2 = evntBuf[i].ct;
- }
- }
- evntSort();
- return;
- }
-
- void evntWrite(void) /* イベントをディスクに出力 */
- {
- int ev;
- int i;
- int j;
- int dummy;
- int running = -1;
-
- unsigned long dt;
-
- for( i=0;i<evntCt;i++ ) {
- dt = ( i==0 ) ? 0 : evntBuf[i].ct-evntBuf[i-1].ct;
- dt = dt * fg.div /48; /* 分解能変換 */
- varNum( dt ); /* TIME */
- ev = evntBuf[i].dat[0];
- if( ev >= 0x80 && ev <= 0xef) {
- if(( running!=ev ) || (( option & RUNNING ) != RUNNING)) {
- putData( 1,ev );
- running = ev;
- }
- if(( ev&0xf0 ) == 0xc0 ) {
- putData( 1 ,evntBuf[i].dat[1] );
- continue;
- }
- putData( 2 ,evntBuf[i].dat[1] ,evntBuf[i].dat[2] );
- continue;
- }
- running = -1;
- if( ev == 0xff ) {
- for( j=0;j<3;j++ )
- putData( 1 ,evntBuf[i].dat[j] );
- continue;
- }
- switch( ev ) {
- case EXCM: /* exclusive message */
- putData( 1 ,0xf0 );
- dummy = (int) evntBuf[i].dat[1];
- varNum( (unsigned long) evntBuf[i].dat[2] + 1 );
- for( j=0;j<(int)evntBuf[i].dat[2];j++ )
- putData( 1 ,(int)exclPt[dummy][j] );
- putData( 1 ,0xf7 );
- break;
- case F7EXCM:
- putData( 1 ,0xf7 );
- dummy = (int) evntBuf[i].dat[1];
- varNum( (unsigned long) evntBuf[i].dat[2] );
- for( j=0;j<(int)evntBuf[i].dat[2];j++ )
- putData( 1 ,(int) exclPt[dummy][j] );
- break;
- case DIRECT:
- dummy = (int) evntBuf[i].dat[1];
- for( j=0;j<(int)evntBuf[i].dat[2];j++ )
- putData( 1 ,(int)exclPt[dummy][j] );
- break;
- case MEMO: /* text */
- case WORDS: /* words */
- dummy = ( ev==WORDS ) ? 5 : 1;
- putData( 2,0xff,dummy );
- dummy = (int) evntBuf[i].dat[1];
- varNum( (unsigned long) evntBuf[i].dat[2] );
- for( j=0;j<(int)evntBuf[i].dat[2];j++ )
- putData( 1 ,(int)exclPt[dummy][j] );
- break;
- case TEMPO: /* tempo */
- putTempo( evntBuf[i].dat[1] * 256 + evntBuf[i].dat[2] );
- break;
- case SIGNATURE: /* signature */
- putSignature( evntBuf[i].dat[1] ,evntBuf[i].dat[2] );
- case 0xf9: /* tyou */
- break;
- }
- }
- return;
- }
-
- /* MMLコマンド類 */
-
- void mmlNote( unsigned short *tc ,int note ) /* ノートオン・オフ/休符 */
- {
- int d;
- int n;
- int len;
- int vel;
- int q;
- int step;
- int dummy;
-
- unsigned short timeCt;
- unsigned short tDummy;
-
- timeCt = *tc;
- n = note;
-
- if( n == 12 ) {
- note = readPara( 0 ,127 ,-1 ,"'n' number" );
- if( readData() == ',' ) rp++;
- }
-
- if( n<12 ) {
- if( (d = readData()) == '+' || d == '#' ){
- note++;
- rp++;
- }
- if( d=='-' ){
- note--;
- rp++;
- }
- note += (dlt_o[nowPart][nowAray]+1) * 12;
- if(key_spart[nowPart] == 0) note = note + key_shift;
- if(note<0 || note>127) errMsg(MSG_syntax,"over note");
- }
-
- step = 0;
- for(;;){
- len = readPara( 1 ,192 ,dlt_l[nowPart][nowAray]
- ,"(note:length)" );
- dummy = 192 / len;
- if( readData() == '.' ) {
- rp++;
- dummy = dummy * 1.5;
- }
- step += dummy;
- if( readData() =='^' ) rp++;
- else break;
- }
-
- if( n != 13 ){
- if( readData() == ',' ) {
- rp++;
- vel = readPara( 1 ,127 ,dlt_v[nowPart][nowAray]
- ,"(note:velocity)" );
- }else vel = dlt_v[nowPart][nowAray];
- if( readData() == ',' ) {
- rp++;
- q = readPara( 1 ,8 ,dlt_q[nowPart][nowAray]
- ,"(note:q)");
- }else q=dlt_q[nowPart][nowAray];
-
- if( tie_flag == TRUE ) {
- if( tie_note == note )
- evntBuf[tie_etct].ct = (unsigned short)( timeCt+step*q/8 );
- else {
- if( tie_note != ERR )
- evntBuf[tie_etct].ct = (unsigned short)(timeCt);
- q = 8;
- tie_flag = FALSE;
- }
- }
- if( tie_flag != TRUE ) {
- evntPut( timeCt ,0x90+fg.part[nowPart] ,note ,vel );
- tie_note = note;
- tie_etct = evntCt;
- tDummy = step*q/8-1;
- if( tDummy < 1 ) tDummy = 1;
- evntPut( timeCt+tDummy ,0x80+fg.part[nowPart]
- ,note ,0x00 );
- }
- }
- timeCt += step;
- *tc = timeCt;
- tie_flag = FALSE;
- return;
- }
- void mmlSub1( unsigned short timeCt ,int cm ) /* MMLコマンド1 */
- {
- char *msg_tempo = "tempo";
-
- int dummy;
- int para;
-
- switch( cm )
- {
- case 'v':
- dlt_v[nowPart][nowAray] = readPara( 0,15,15,EMG_v )*8+7;
- break;
- case 'o':
- dlt_o[nowPart][nowAray] = readPara( 1,8,4,EMG_o);
- break;
- case 'q':
- dlt_q[nowPart][nowAray] = readPara( 1,8,8,EMG_q );
- break;
- case 'l':
- dlt_l[nowPart][nowAray] = readPara( 1,192,4,EMG_l );
- break;
- case '>':
- dlt_o[nowPart][nowAray] += 2;
- case '<':
- dlt_o[nowPart][nowAray] --;
- dummy = dlt_o[nowPart][nowAray];
- if( dummy < 1 || dummy > 8 )
- errMsg( MSG_illfnc ,"'>or<' octave over" );
- break;
- case ']':
- case '[':
- dummy = readPara( 0,127,8,EMG_v )*((cm==']')?1:-1);
- dummy += dlt_v[nowPart][nowAray];
- if( dummy<0 || dummy>127 )
- errMsg( MSG_illfnc ,"']or[' velocity over" );
- dlt_v[nowPart][nowAray] = dummy;
- break;
- case 'u':
- para = readPara( -8192,8191,0,"pitch bend" )+8192;
- evntPut( timeCt,0xE0+fg.part[nowPart],para&0x7f,(para&0x3f80)>>7 );
- break;
- case 't':
- dummy = readData();
- if( dummy=='+' || dummy=='-' ) {
- rp++;
- para = readPara( 0,256,5,msg_tempo );
- fg.tempo += para*(( dummy=='+' )?1:-1);
- } else
- fg.tempo = readPara( 30,600,120,msg_tempo );
- evntPut( timeCt,TEMPO,(fg.tempo&0xff00)>>8,fg.tempo&0xff );
- break;
- default:
- errMsg( MSG_unperr ,NULL );
- }
- return;
- }
-
- void mmlSub2( unsigned short timeCt ) /* MMLコマンド2 */
- {
- char *msg_c = "control change";
- char *msg_s = "signature";
- char *msg_x = "exclusive";
- char *msg_m = "memo or words";
-
- char ex[256];
-
- int cm2;
- int para;
- int para2;
- int dummy;
- int i;
- int j;
-
- cm2 = tolower(readData());
- rp++;
- switch( cm2 ) {
- case 'a':
- para = readPara( 0,127,0,NULL );
- break;
- case 'c':
- para = readPara( 0,127,-1,msg_c );
- if( readData() != '/' )
- errMsg( MSG_syntax,msg_c );
- rp++;
- para2 = readPara( 0,127,-1,msg_c );
- evntPut( timeCt,0xB0+fg.part[nowPart],para,para2 );
- break;
- case 'v':
- dlt_v[nowPart][nowAray] = readPara( 0,127,127,EMG_v );
- break;
- case 's':
- para = readPara( 1,64,-1,msg_s );
- if( readData() != '/' )
- errMsg( MSG_syntax ,msg_s );
- rp++;
- para2 = readPara( 1,64,-1,msg_s );
- evntPut( timeCt,SIGNATURE,para,para2 );
- fg.signature[0] = para;
- fg.signature[1] = para2;
- break;
- case 'd':
- case 'r':
- case 'f':
- case 'x':
- if( readData() != '[' )
- errMsg( MSG_syntax,msg_x );
- rp++;
- i=0;
- for(;;) {
- dummy = readData();
- if( dummy == ']' ) break;
- if( dummy == '\0' ) {
- skipLine( &rp );
- continue;
- }
- para = 0;
- for( j=0;j<2;j++ ) {
- dummy = readData();
- rp++;
- if( dummy == '%' ) {
- if( j != 0 )
- errMsg( MSG_syntax,msg_x );
- para=readPara( 0,255,-1,msg_x );
- if( readData() != '%' )
- errMsg( MSG_syntax,msg_x );
- rp++;
- break;
- }
- if( toupper(dummy) == 'X' ) {
- dummy=fg.part[nowPart];
- dummy=(dummy != 9)?dummy:-1;
- if(dummy<9) dummy++;
- }
- else if( toupper(dummy) == 'P' ) {
- dummy = fg.part[nowPart];
- }
- else
- dummy = instr("0123456789ABCDEF",toupper(dummy));
- if( dummy == ERR )
- errMsg( MSG_syntax,msg_x );
- para = para*16+dummy;
- }
- ex[i] = para;
- if( ++i > 255 )
- errMsg( MSG_syntax,msg_x );
- }
- rp++;
- if ( cm2 == 'r' ) { /* ROLAND EX. CHECK SUM */
- if( i == 255 )
- errMsg(MSG_syntax,msg_x);
- dummy = 0;
- for( j=4;j<i;j++ ) dummy += ex[j];
- dummy = CHECKSUM(dummy);
- ex[i++] = dummy;
- }
- if( cm2 == 'f' ) dummy = F7EXCM;
- else if( cm2 == 'd' ) dummy = DIRECT;
- else dummy = EXCM;
- exclBank( timeCt,dummy,i,ex );
- break;
- case 'm': /* メモ・歌詞はエクスクルーシブ領域を代用する */
- case 'w':
- if( readData() != '"' )
- errMsg( MSG_syntax,msg_m );
- rp++;
- i = 0;
- for(;;) {
- dummy=*rp;
- if( dummy=='"' ) break;
- if( dummy=='\0' ) {
- skipLine( &rp );
- continue;
- }
- rp++;
- ex[i] = dummy;
- if( ++i > 255 ) break;
- }
- rp++;
- dummy = (cm2=='w')?WORDS:MEMO;
- exclBank( timeCt,dummy,i,ex );
- break;
- case 'h':
- fg.part[nowPart] = readPara( 1,16,0,"'@H'" )-1;
- break;
- case 'k':
- dummy = toupper(readData());
- rp++;
- if( dummy == 'S' ) {
- para = readPara( 1,16,0,"'@KS'")-1;
- key_spart[para]=1;
- } else
- if( dummy == 'U' || dummy == 'D' )
- key_shift = readPara(0,24,-1,"'@KU/@KD'") * ((dummy == 'U')?1:-1);
- else errMsg(MSG_syntax,"Key Shift");
- break;
- default:
- rp--;
- dummy = readPara( 0,128,-1,"program change" );
- para = fg.program[dummy]-1;
- if( para<0 || para >127 )
- errMsg( MSG_illfnc,"program change" );
- evntPut( timeCt,0xC0+fg.part[nowPart],para,0x00 );
- break;
- }
- return;
- }
- void mmlSub3( unsigned int t ) /* ”%”コマンド */
- {
- int comNum;
- int clChg;
- int mode;
- int min;
- int max;
- int a;
- int b;
- int defl;
- int para = 0;
-
- comNum = toupper( readData() );
-
- if( comNum ==ERR || comNum < 'A' || comNum > 'Z' )
- errMsg( MSG_syntax ,"('%')" );
- rp++;
-
- comNum = comNum - 'A';
- clChg = ctrlMacro[comNum][0];
- mode = ctrlMacro[comNum][1];
- min = ctrlMacro[comNum][2];
- max = ctrlMacro[comNum][3];
- a = ctrlMacro[comNum][4];
- b = ctrlMacro[comNum][5];
- defl = ctrlMacro[comNum][6];
-
- if( clChg == ERR )
- errMsg( MSG_syntax ,"('%')" );
- if( mode != 1 )
- para = readPara( min ,max ,defl ,"('%' para)" );
- para = para * b + a;
- evntPut( t ,0xB0+fg .part[nowPart] ,clChg ,para );
- return;
- }
-
- void mmlSub4( unsigned short *tc ) /* タイムポインター系 */
- {
- int c;
- int d;
- unsigned short timeCt;
-
- timeCt = *tc;
- c = tolower( readData() );
- rp++;
-
- switch( c ) {
- case 's':
- d = readPara( 1 ,128 ,0 ,"MARK" ) - 1;
- setTime[d] = timeCt;
- break;
- case 'm':
- timeCt = ( readPara( 1,256,0,"MEAS" ) -1 ) * fg.signature[0] * 192 / fg.signature[1];
- break;
- case 'i':
- printf( "info. :Time/%u O/%d L/%d @V/%d Q/%d\n",timeCt,
- dlt_o[nowPart][nowAray] ,dlt_l[nowPart][nowAray],
- dlt_v[nowPart][nowAray] ,dlt_q[nowPart][nowAray]);
- break;
- default:
- rp--;
- d = readPara( 1,128,0,"MARK" ) - 1;
- timeCt = setTime[d];
- break;
- }
- *tc = timeCt;
- return;
- }
-
- void mmlRhythm( unsigned short *tc ,int cm ) /* リズム用サブコマンド */
- {
- char *msg = "Rhythm Track";
- char buf[64];
-
- int num = 1;
- int len;
- int step;
- int dummy;
- int note;
- int vel;
- int i;
-
- buf[0] = cm;
-
- for(;;) {
- cm = tolower( readData() );
-
- if( cm == '!' ) {
- rp++;
- continue;
- }
-
- if( cm == 'r' )
- errMsg( MSG_syntax ,msg );
-
- if( cm >= 'a' && cm <= 'z' ) {
- buf[num] = cm;
- num++;
- if( num >= 64 )
- errMsg( MSG_syntax ,msg );
- rp++;
- continue;
- }
- break;
- }
-
- step = 0;
-
- for(;;) {
- len = readPara( 1 ,192 ,0 ,msg );
- dummy = 192 / len;
-
- if( readData()=='.') {
- rp++;
- dummy = dummy * 1.5;
- }
- step += dummy;
- if( readData() == '^' )
- rp++;
- else break;
- }
-
- for( i=0;i<num;i++ ) {
- dummy = buf[i] - 'a';
- note = fg.rnote[dummy][0];
- vel = fg.rnote[dummy][1];
- if( note == ERR )
- errMsg( MSG_undmml ,"Rhythm" );
- evntPut( *tc ,0x90+fg .part[nowPart] ,note ,vel );
- evntPut( *tc+1 ,0x80+fg .part[nowPart] ,note ,0x00 );
- }
- *tc += step;
- return;
- }
-
- void mmlComp( void ) /* MMLコマンド分岐 */
- {
- char buf[32];
-
- int cm;
- int note;
- int maxSTC = 0;
-
- unsigned short timeCt = 0;
- unsigned short sTimeCt[32][2];
-
- tie_flag = FALSE;
- tie_note = ERR;
-
- for(;;) {
- if( timeCt > maxTCt )
- maxTCt = timeCt;
- cm = tolower( readData() );
- if( cm == '\0' )
- errMsg( MSG_freerr ,"MML not end" );
- if( cm == '}' ) {
- printf( "Warning:" );
- printf( MSG_misopd ,"';'" );
- break;
- }
- rp++;
- if( cm == ';' )
- break;
- if( fg.rpart == nowPart ) {
- if( cm >= 'a' && cm <= 'z' && cm != 'r' ) {
- mmlRhythm( &timeCt ,cm );
- continue;
- }
- }
- if(( note = instr( "c d ef g a bnr" ,cm )) != ERR ) {
- mmlNote( &timeCt ,note );
- continue;
- }
- if( instr( "voql><[]ut" ,cm ) != ERR ) {
- mmlSub1( timeCt ,cm );
- continue;
- }
- if( cm == '@' ) {
- mmlSub2( timeCt );
- continue;
- }
- if( cm == '%' ) {
- mmlSub3( timeCt );
- continue;
- }
- if( cm == '*' ) {
- mmlSub4( &timeCt );
- continue;
- }
- if( cm == '&' ) {
- tie_flag=TRUE;
- continue;
- }
- if( cm == '_' ) {
- itlMacro( &rp ,&timeCt ,&exclCt ,fg.part[nowPart] );
- continue;
- }
- switch( cm ) {
- case '(':
- if( maxSTC >= 32 )
- errMsg( MSG_toonst ,"Chord" );
- sTimeCt[maxSTC][0] = timeCt;
- sTimeCt[maxSTC][1] = timeCt;
- maxSTC++;
- break;
- case '|':
- if( maxSTC == 0 )
- errMsg( MSG_syntax ,"chord:'|'" );
- if( timeCt > sTimeCt[maxSTC-1][1] )
- sTimeCt[maxSTC-1][1] = timeCt;
- timeCt = sTimeCt[maxSTC-1][0];
- break;
- case ')':
- if( maxSTC == 0 )
- errMsg( MSG_syntax ,"chord:')'" );
- maxSTC--;
- timeCt = sTimeCt[maxSTC][1];
- break;
- }
- if( instr( "(|)" ,cm ) != ERR )
- continue;
-
- sprintf( buf ,"undefined MML '%c'" ,cm );
- errMsg( MSG_syntax ,buf );
- }
- if( maxSTC != 0 ) {
- printf( "Warning:" );
- printf( MSG_misopd ,"chord" );
- }
- if( timeCt > maxTCt )
- maxTCt = timeCt;
- return;
- }
-
- int mmlLine( FLGDAT fgDummy ,WORKMEM *w ,int orf ) /* MML行メイン */
- {
- int i;
-
- option = orf;
- evntBuf = w;
- fg = fgDummy;
-
- if(( rp = Pre_fgets() ) == NULL )
- errMsg( MSG_freerr ,"No MML data" );
- dltSet();
-
- for( i=0;i<128;i++ )
- setTime[i] = 0;
-
- for(;;) {
- if( blockName() == FAILURE )
- break;
- for( i=0;i<PART_MAX;i++ )
- dltAray[i] = 0; /* 配列初期化 */
- evntCt = 0;
- exclCt = 0;
- maxTCt = 0;
- for(;;) {
- if( readData() == '}' ) {
- rp++;
- break;
- }
- getPart();
- mmlComp();
- }
- evntPut( maxTCt ,0xff ,0x06 ,0x00 );
-
- if(( option & HISPCMP ) != HISPCMP )
- evntSort();
- else evntSort2();
- if(( option & SHIFTST ) == SHIFTST )
- evntRtch();
- evntWrite();
- if(( option & CHECKMD ) == CHECKMD )
- evntCheck();
- for( i=0;i<exclCt;i++ )
- free( exclPt[i] );
- }
- return( SUCCSESS );
- }
-